#include <iostream>
#include <stdio.h>
#include <math.h>

#include <SDL/SDL.h>

#include "Object3D.h"

Object3D::Object3D
(const char *path): 
  nFaces(0), nVertices(0), 
  rotation(0.0), increment(ROTATION_INCREMENT)
{
  int i = 0, line = 0;
  char staux[MAXLINE];
  float a, b, c;
  GLdouble aux[3];
  float vx, vy, vz;
  FILE *f;
  
  if(!(f = fopen (path, "r")))
    {
      cerr << "File: " << path << " not found!" << endl;
      exit(-1);
    }
  
  while (fgets(staux, MAXLINE, f)!=NULL){

    line++;

    switch(staux[0]){

      // Comment.
    case '#': break;

      // Vertex.
    case 'v': 

      // Read the x, y and z values.
      sscanf(&staux[2], "%f %f %f", &vx, &vy, &vz);

      aux[0] = vx; aux[1] = vy; aux[2] = vz;
      // Append a new vertex.
      vertices.push_back(new Vertex3D(aux));
      nVertices++;

      break;

      // Face.
    case 'f': 

      sscanf(&staux[2], "%f %f %f", &a, &b, &c);

      // Store the vertex pointers.
      faces.push_back(new Face(vertices[--a],
      			       vertices[--b],
      			       vertices[--c]));

      nFaces++;

      break;

    default: break;

    }// End switch.

  }// End while.

  fclose (f);

}
 
Object3D::~Object3D ()
{
  for (vector<Vertex3D*>::iterator it = vertices.begin();
       it != vertices.end();
       ++it)
    delete *it;

  for (vector<Face*>::iterator it = faces.begin();
       it != faces.end();
       ++it)
    delete *it;
}

GLdouble
Object3D::incrementRotationAngle ()
{
  rotation += increment;
  return rotation;
}

int
Object3D::numberOfFaces()
{
  return nFaces;
}
 
int
Object3D::numberOfVertices()
{
  return nVertices;
}

void
Object3D::draw ()
{
  glPushMatrix();
  // Update the rotation angle.
  glRotatef(incrementRotationAngle(), 0.0, 1.0, 0.0);

  for (vector<Face*>::iterator it = faces.begin();
       it != faces.end();
       it++)
    {
      glBegin(GL_TRIANGLES);  

      glNormal3dv((*it)->v1()->normal());
      glVertex3dv((*it)->v1()->pos());

      glNormal3dv((*it)->v2()->normal());
      glVertex3dv((*it)->v2()->pos());

      glNormal3dv((*it)->v3()->normal());
      glVertex3dv((*it)->v3()->pos());

      glEnd();
    }

  glPopMatrix();
  glFlush();
}

void
Object3D::computeNormals ()
{
}
